#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
设备管理系统 - Equipment Management System

功能包括：
- 设备档案管理
- 设备维护计划管理
- 设备故障管理
- 设备性能监控分析
"""

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
import json
import logging
from dataclasses import dataclass, asdict
from enum import Enum
import uuid
from collections import defaultdict
import statistics

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class EquipmentStatus(Enum):
    """设备状态枚举"""
    OPERATIONAL = "operational"     # 运行中
    IDLE = "idle"                   # 空闲
    MAINTENANCE = "maintenance"     # 维护中
    BREAKDOWN = "breakdown"         # 故障
    RETIRED = "retired"             # 报废
    UNDER_REPAIR = "under_repair"   # 维修中

class MaintenanceType(Enum):
    """维护类型枚举"""
    PREVENTIVE = "preventive"       # 预防性维护
    CORRECTIVE = "corrective"       # 纠正性维护
    PREDICTIVE = "predictive"       # 预测性维护
    EMERGENCY = "emergency"         # 紧急维护
    ROUTINE = "routine"             # 例行维护

class MaintenanceStatus(Enum):
    """维护状态枚举"""
    PLANNED = "planned"             # 已计划
    IN_PROGRESS = "in_progress"     # 进行中
    COMPLETED = "completed"         # 已完成
    CANCELLED = "cancelled"         # 已取消
    OVERDUE = "overdue"             # 逾期

class FaultSeverity(Enum):
    """故障严重程度枚举"""
    CRITICAL = "critical"           # 严重
    HIGH = "high"                   # 高
    MEDIUM = "medium"               # 中等
    LOW = "low"                     # 低

class FaultStatus(Enum):
    """故障状态枚举"""
    REPORTED = "reported"           # 已报告
    INVESTIGATING = "investigating" # 调查中
    REPAIRING = "repairing"         # 维修中
    RESOLVED = "resolved"           # 已解决
    CLOSED = "closed"               # 已关闭

@dataclass
class Equipment:
    """设备信息"""
    equipment_id: str
    name: str
    model: str
    manufacturer: str
    serial_number: str
    category: str
    location: str
    purchase_date: datetime
    warranty_expiry: datetime
    status: str = EquipmentStatus.OPERATIONAL.value
    specifications: Dict[str, str] = None
    operating_parameters: Dict[str, float] = None
    installation_date: Optional[datetime] = None
    last_maintenance_date: Optional[datetime] = None
    next_maintenance_date: Optional[datetime] = None
    total_operating_hours: float = 0.0
    purchase_cost: float = 0.0
    current_value: float = 0.0
    is_active: bool = True
    created_date: datetime = None
    
    def __post_init__(self):
        if self.specifications is None:
            self.specifications = {}
        if self.operating_parameters is None:
            self.operating_parameters = {}
        if self.created_date is None:
            self.created_date = datetime.now()
        if self.installation_date is None:
            self.installation_date = self.purchase_date

@dataclass
class MaintenancePlan:
    """维护计划"""
    plan_id: str
    equipment_id: str
    maintenance_type: str
    description: str
    frequency_days: int  # 维护频率（天）
    estimated_duration_hours: float
    required_parts: List[Dict] = None  # 所需零件
    required_skills: List[str] = None  # 所需技能
    safety_requirements: List[str] = None  # 安全要求
    cost_estimate: float = 0.0
    is_active: bool = True
    created_date: datetime = None
    
    def __post_init__(self):
        if self.required_parts is None:
            self.required_parts = []
        if self.required_skills is None:
            self.required_skills = []
        if self.safety_requirements is None:
            self.safety_requirements = []
        if self.created_date is None:
            self.created_date = datetime.now()

@dataclass
class MaintenanceTask:
    """维护任务"""
    task_id: str
    plan_id: str
    equipment_id: str
    maintenance_type: str
    description: str
    scheduled_date: datetime
    estimated_duration_hours: float
    assigned_technician: str = ""
    status: str = MaintenanceStatus.PLANNED.value
    actual_start_time: Optional[datetime] = None
    actual_end_time: Optional[datetime] = None
    actual_duration_hours: float = 0.0
    parts_used: List[Dict] = None
    labor_cost: float = 0.0
    parts_cost: float = 0.0
    total_cost: float = 0.0
    notes: str = ""
    completion_notes: str = ""
    created_date: datetime = None
    
    def __post_init__(self):
        if self.parts_used is None:
            self.parts_used = []
        if self.created_date is None:
            self.created_date = datetime.now()

@dataclass
class FaultRecord:
    """故障记录"""
    fault_id: str
    equipment_id: str
    fault_description: str
    severity: str
    reported_by: str
    reported_date: datetime
    status: str = FaultStatus.REPORTED.value
    assigned_technician: str = ""
    root_cause: str = ""
    resolution_description: str = ""
    downtime_hours: float = 0.0
    repair_cost: float = 0.0
    parts_replaced: List[Dict] = None
    resolved_date: Optional[datetime] = None
    impact_on_production: str = ""
    preventive_actions: List[str] = None
    created_date: datetime = None
    
    def __post_init__(self):
        if self.parts_replaced is None:
            self.parts_replaced = []
        if self.preventive_actions is None:
            self.preventive_actions = []
        if self.created_date is None:
            self.created_date = datetime.now()

@dataclass
class PerformanceMetric:
    """性能指标"""
    metric_id: str
    equipment_id: str
    metric_name: str
    metric_value: float
    unit: str
    recorded_date: datetime
    operator_id: str = ""
    notes: str = ""
    is_within_normal_range: bool = True
    normal_range_min: Optional[float] = None
    normal_range_max: Optional[float] = None
    
    def __post_init__(self):
        # 检查是否在正常范围内
        if self.normal_range_min is not None and self.normal_range_max is not None:
            self.is_within_normal_range = (
                self.normal_range_min <= self.metric_value <= self.normal_range_max
            )

class EquipmentManagementSystem:
    """设备管理系统核心类"""
    
    def __init__(self):
        self.equipment: Dict[str, Equipment] = {}
        self.maintenance_plans: Dict[str, MaintenancePlan] = {}
        self.maintenance_tasks: Dict[str, MaintenanceTask] = {}
        self.fault_records: Dict[str, FaultRecord] = {}
        self.performance_metrics: List[PerformanceMetric] = []
        self.technicians: Dict[str, Dict] = {}  # 技术员信息
        
    def register_equipment(self, equipment: Equipment) -> bool:
        """注册设备"""
        try:
            self.equipment[equipment.equipment_id] = equipment
            logger.info(f"设备 {equipment.name} ({equipment.equipment_id}) 注册成功")
            return True
        except Exception as e:
            logger.error(f"设备注册失败: {e}")
            return False
    
    def update_equipment_status(self, equipment_id: str, status: str, 
                              notes: str = "") -> bool:
        """更新设备状态"""
        if equipment_id not in self.equipment:
            logger.error(f"设备 {equipment_id} 不存在")
            return False
        
        try:
            old_status = self.equipment[equipment_id].status
            self.equipment[equipment_id].status = status
            
            logger.info(f"设备 {equipment_id} 状态从 {old_status} 更新为 {status}")
            return True
            
        except Exception as e:
            logger.error(f"更新设备状态失败: {e}")
            return False
    
    def register_technician(self, technician_data: Dict) -> bool:
        """注册技术员"""
        try:
            technician_id = technician_data['technician_id']
            self.technicians[technician_id] = {
                'name': technician_data['name'],
                'skills': technician_data.get('skills', []),
                'certifications': technician_data.get('certifications', []),
                'experience_years': technician_data.get('experience_years', 0),
                'hourly_rate': technician_data.get('hourly_rate', 0.0),
                'is_available': technician_data.get('is_available', True)
            }
            logger.info(f"技术员 {technician_data['name']} 注册成功")
            return True
        except Exception as e:
            logger.error(f"技术员注册失败: {e}")
            return False
    
    def create_maintenance_plan(self, plan_data: Dict) -> Optional[str]:
        """创建维护计划"""
        try:
            plan_id = f"MP{datetime.now().strftime('%Y%m%d%H%M%S')}{str(uuid.uuid4())[:6]}"
            
            plan = MaintenancePlan(
                plan_id=plan_id,
                equipment_id=plan_data['equipment_id'],
                maintenance_type=plan_data['maintenance_type'],
                description=plan_data['description'],
                frequency_days=plan_data['frequency_days'],
                estimated_duration_hours=plan_data['estimated_duration_hours'],
                required_parts=plan_data.get('required_parts', []),
                required_skills=plan_data.get('required_skills', []),
                safety_requirements=plan_data.get('safety_requirements', []),
                cost_estimate=plan_data.get('cost_estimate', 0.0)
            )
            
            self.maintenance_plans[plan_id] = plan
            
            # 为设备生成下次维护日期
            self._update_next_maintenance_date(plan_data['equipment_id'], plan_id)
            
            logger.info(f"维护计划 {plan_id} 创建成功")
            return plan_id
            
        except Exception as e:
            logger.error(f"创建维护计划失败: {e}")
            return None
    
    def _update_next_maintenance_date(self, equipment_id: str, plan_id: str):
        """更新设备下次维护日期"""
        if equipment_id not in self.equipment or plan_id not in self.maintenance_plans:
            return
        
        equipment = self.equipment[equipment_id]
        plan = self.maintenance_plans[plan_id]
        
        # 计算下次维护日期
        if equipment.last_maintenance_date:
            next_date = equipment.last_maintenance_date + timedelta(days=plan.frequency_days)
        else:
            next_date = datetime.now() + timedelta(days=plan.frequency_days)
        
        equipment.next_maintenance_date = next_date
    
    def generate_maintenance_tasks(self, days_ahead: int = 30) -> List[str]:
        """生成维护任务"""
        generated_tasks = []
        end_date = datetime.now() + timedelta(days=days_ahead)
        
        for equipment_id, equipment in self.equipment.items():
            if not equipment.is_active or equipment.status == EquipmentStatus.RETIRED.value:
                continue
            
            # 检查是否需要生成维护任务
            if (equipment.next_maintenance_date and 
                equipment.next_maintenance_date <= end_date):
                
                # 查找对应的维护计划
                for plan in self.maintenance_plans.values():
                    if (plan.equipment_id == equipment_id and 
                        plan.is_active):
                        
                        task_id = self._create_maintenance_task_from_plan(plan)
                        if task_id:
                            generated_tasks.append(task_id)
        
        logger.info(f"生成了 {len(generated_tasks)} 个维护任务")
        return generated_tasks
    
    def _create_maintenance_task_from_plan(self, plan: MaintenancePlan) -> Optional[str]:
        """从维护计划创建维护任务"""
        try:
            task_id = f"MT{datetime.now().strftime('%Y%m%d%H%M%S')}{str(uuid.uuid4())[:6]}"
            
            equipment = self.equipment[plan.equipment_id]
            scheduled_date = equipment.next_maintenance_date or datetime.now()
            
            task = MaintenanceTask(
                task_id=task_id,
                plan_id=plan.plan_id,
                equipment_id=plan.equipment_id,
                maintenance_type=plan.maintenance_type,
                description=plan.description,
                scheduled_date=scheduled_date,
                estimated_duration_hours=plan.estimated_duration_hours
            )
            
            self.maintenance_tasks[task_id] = task
            
            # 自动分配技术员
            self._auto_assign_technician(task_id, plan.required_skills)
            
            return task_id
            
        except Exception as e:
            logger.error(f"创建维护任务失败: {e}")
            return None
    
    def _auto_assign_technician(self, task_id: str, required_skills: List[str]):
        """自动分配技术员"""
        if task_id not in self.maintenance_tasks:
            return
        
        # 查找具备所需技能的可用技术员
        suitable_technicians = []
        
        for tech_id, tech_info in self.technicians.items():
            if not tech_info['is_available']:
                continue
            
            # 检查技能匹配
            tech_skills = set(tech_info['skills'])
            required_skills_set = set(required_skills)
            
            if required_skills_set.issubset(tech_skills):
                suitable_technicians.append((tech_id, tech_info))
        
        # 选择经验最丰富的技术员
        if suitable_technicians:
            best_technician = max(suitable_technicians, 
                                key=lambda x: x[1]['experience_years'])
            
            self.maintenance_tasks[task_id].assigned_technician = best_technician[0]
            logger.info(f"任务 {task_id} 已分配给技术员 {best_technician[1]['name']}")
    
    def start_maintenance_task(self, task_id: str, technician_id: str = "") -> bool:
        """开始维护任务"""
        if task_id not in self.maintenance_tasks:
            return False
        
        try:
            task = self.maintenance_tasks[task_id]
            
            if technician_id:
                task.assigned_technician = technician_id
            
            task.status = MaintenanceStatus.IN_PROGRESS.value
            task.actual_start_time = datetime.now()
            
            # 更新设备状态
            self.update_equipment_status(task.equipment_id, 
                                       EquipmentStatus.MAINTENANCE.value)
            
            logger.info(f"维护任务 {task_id} 已开始")
            return True
            
        except Exception as e:
            logger.error(f"开始维护任务失败: {e}")
            return False
    
    def complete_maintenance_task(self, task_id: str, completion_data: Dict) -> bool:
        """完成维护任务"""
        if task_id not in self.maintenance_tasks:
            return False
        
        try:
            task = self.maintenance_tasks[task_id]
            
            task.status = MaintenanceStatus.COMPLETED.value
            task.actual_end_time = datetime.now()
            
            if task.actual_start_time:
                duration = (task.actual_end_time - task.actual_start_time).total_seconds() / 3600
                task.actual_duration_hours = duration
            
            # 更新任务信息
            if 'parts_used' in completion_data:
                task.parts_used = completion_data['parts_used']
            
            if 'labor_cost' in completion_data:
                task.labor_cost = completion_data['labor_cost']
            
            if 'parts_cost' in completion_data:
                task.parts_cost = completion_data['parts_cost']
            
            task.total_cost = task.labor_cost + task.parts_cost
            
            if 'completion_notes' in completion_data:
                task.completion_notes = completion_data['completion_notes']
            
            # 更新设备信息
            equipment = self.equipment[task.equipment_id]
            equipment.last_maintenance_date = task.actual_end_time
            equipment.status = EquipmentStatus.OPERATIONAL.value
            
            # 更新下次维护日期
            self._update_next_maintenance_date(task.equipment_id, task.plan_id)
            
            logger.info(f"维护任务 {task_id} 已完成")
            return True
            
        except Exception as e:
            logger.error(f"完成维护任务失败: {e}")
            return False
    
    def report_fault(self, fault_data: Dict) -> Optional[str]:
        """报告故障"""
        try:
            fault_id = f"FT{datetime.now().strftime('%Y%m%d%H%M%S')}{str(uuid.uuid4())[:6]}"
            
            fault = FaultRecord(
                fault_id=fault_id,
                equipment_id=fault_data['equipment_id'],
                fault_description=fault_data['fault_description'],
                severity=fault_data.get('severity', FaultSeverity.MEDIUM.value),
                reported_by=fault_data['reported_by'],
                reported_date=fault_data.get('reported_date', datetime.now()),
                impact_on_production=fault_data.get('impact_on_production', '')
            )
            
            self.fault_records[fault_id] = fault
            
            # 根据严重程度更新设备状态
            if fault.severity in [FaultSeverity.CRITICAL.value, FaultSeverity.HIGH.value]:
                self.update_equipment_status(fault.equipment_id, 
                                           EquipmentStatus.BREAKDOWN.value)
            
            # 自动分配技术员
            self._auto_assign_fault_technician(fault_id)
            
            logger.info(f"故障 {fault_id} 已报告")
            return fault_id
            
        except Exception as e:
            logger.error(f"报告故障失败: {e}")
            return None
    
    def _auto_assign_fault_technician(self, fault_id: str):
        """自动分配故障处理技术员"""
        if fault_id not in self.fault_records:
            return
        
        fault = self.fault_records[fault_id]
        equipment = self.equipment[fault.equipment_id]
        
        # 查找可用技术员，优先考虑经验和可用性
        available_technicians = [
            (tech_id, tech_info) for tech_id, tech_info in self.technicians.items()
            if tech_info['is_available']
        ]
        
        if available_technicians:
            # 根据严重程度和经验选择技术员
            if fault.severity == FaultSeverity.CRITICAL.value:
                # 严重故障分配给最有经验的技术员
                best_technician = max(available_technicians, 
                                    key=lambda x: x[1]['experience_years'])
            else:
                # 其他故障可以分配给任何可用技术员
                best_technician = available_technicians[0]
            
            fault.assigned_technician = best_technician[0]
            logger.info(f"故障 {fault_id} 已分配给技术员 {best_technician[1]['name']}")
    
    def update_fault_status(self, fault_id: str, status_data: Dict) -> bool:
        """更新故障状态"""
        if fault_id not in self.fault_records:
            return False
        
        try:
            fault = self.fault_records[fault_id]
            
            if 'status' in status_data:
                fault.status = status_data['status']
            
            if 'assigned_technician' in status_data:
                fault.assigned_technician = status_data['assigned_technician']
            
            if 'root_cause' in status_data:
                fault.root_cause = status_data['root_cause']
            
            if 'resolution_description' in status_data:
                fault.resolution_description = status_data['resolution_description']
            
            if 'repair_cost' in status_data:
                fault.repair_cost = status_data['repair_cost']
            
            if 'parts_replaced' in status_data:
                fault.parts_replaced = status_data['parts_replaced']
            
            if 'preventive_actions' in status_data:
                fault.preventive_actions = status_data['preventive_actions']
            
            # 如果故障已解决，更新设备状态和计算停机时间
            if status_data.get('status') == FaultStatus.RESOLVED.value:
                fault.resolved_date = datetime.now()
                
                # 计算停机时间
                if fault.reported_date:
                    downtime = (fault.resolved_date - fault.reported_date).total_seconds() / 3600
                    fault.downtime_hours = downtime
                
                # 恢复设备状态
                self.update_equipment_status(fault.equipment_id, 
                                           EquipmentStatus.OPERATIONAL.value)
            
            logger.info(f"故障 {fault_id} 状态已更新")
            return True
            
        except Exception as e:
            logger.error(f"更新故障状态失败: {e}")
            return False
    
    def record_performance_metric(self, metric_data: Dict) -> bool:
        """记录性能指标"""
        try:
            metric_id = f"PM{datetime.now().strftime('%Y%m%d%H%M%S')}{str(uuid.uuid4())[:6]}"
            
            metric = PerformanceMetric(
                metric_id=metric_id,
                equipment_id=metric_data['equipment_id'],
                metric_name=metric_data['metric_name'],
                metric_value=metric_data['metric_value'],
                unit=metric_data['unit'],
                recorded_date=metric_data.get('recorded_date', datetime.now()),
                operator_id=metric_data.get('operator_id', ''),
                notes=metric_data.get('notes', ''),
                normal_range_min=metric_data.get('normal_range_min'),
                normal_range_max=metric_data.get('normal_range_max')
            )
            
            self.performance_metrics.append(metric)
            
            # 如果指标异常，记录警告
            if not metric.is_within_normal_range:
                logger.warning(f"设备 {metric.equipment_id} 的 {metric.metric_name} 指标异常: {metric.metric_value} {metric.unit}")
            
            return True
            
        except Exception as e:
            logger.error(f"记录性能指标失败: {e}")
            return False
    
    def get_equipment_performance_analysis(self, equipment_id: str, 
                                         days: int = 30) -> Dict:
        """获取设备性能分析"""
        if equipment_id not in self.equipment:
            return {'error': '设备不存在'}
        
        end_date = datetime.now()
        start_date = end_date - timedelta(days=days)
        
        # 筛选时间范围内的性能指标
        period_metrics = [
            metric for metric in self.performance_metrics
            if (metric.equipment_id == equipment_id and 
                start_date <= metric.recorded_date <= end_date)
        ]
        
        if not period_metrics:
            return {'message': '指定时间范围内无性能数据'}
        
        # 按指标名称分组
        metrics_by_name = defaultdict(list)
        for metric in period_metrics:
            metrics_by_name[metric.metric_name].append(metric)
        
        # 分析各项指标
        performance_analysis = {}
        
        for metric_name, metrics in metrics_by_name.items():
            values = [m.metric_value for m in metrics]
            
            analysis = {
                'metric_name': metric_name,
                'unit': metrics[0].unit if metrics else '',
                'total_records': len(values),
                'average_value': round(statistics.mean(values), 2),
                'min_value': min(values),
                'max_value': max(values),
                'std_deviation': round(statistics.stdev(values), 2) if len(values) > 1 else 0,
                'normal_range_violations': len([m for m in metrics if not m.is_within_normal_range]),
                'trend': 'stable'
            }
            
            # 简单趋势分析
            if len(values) >= 5:
                recent_avg = statistics.mean(values[-5:])
                earlier_avg = statistics.mean(values[:5])
                
                if recent_avg > earlier_avg * 1.1:
                    analysis['trend'] = 'increasing'
                elif recent_avg < earlier_avg * 0.9:
                    analysis['trend'] = 'decreasing'
            
            performance_analysis[metric_name] = analysis
        
        # 设备基本信息
        equipment = self.equipment[equipment_id]
        
        return {
            'equipment_info': {
                'equipment_id': equipment_id,
                'name': equipment.name,
                'model': equipment.model,
                'status': equipment.status,
                'total_operating_hours': equipment.total_operating_hours
            },
            'analysis_period': {
                'start_date': start_date.isoformat(),
                'end_date': end_date.isoformat(),
                'days': days
            },
            'performance_metrics': performance_analysis,
            'overall_health_score': self._calculate_equipment_health_score(equipment_id)
        }
    
    def _calculate_equipment_health_score(self, equipment_id: str) -> float:
        """计算设备健康评分"""
        if equipment_id not in self.equipment:
            return 0.0
        
        equipment = self.equipment[equipment_id]
        score = 100.0
        
        # 基于设备状态扣分
        if equipment.status == EquipmentStatus.BREAKDOWN.value:
            score -= 50
        elif equipment.status == EquipmentStatus.MAINTENANCE.value:
            score -= 20
        elif equipment.status == EquipmentStatus.UNDER_REPAIR.value:
            score -= 30
        
        # 基于故障记录扣分
        recent_faults = [
            fault for fault in self.fault_records.values()
            if (fault.equipment_id == equipment_id and 
                fault.reported_date >= datetime.now() - timedelta(days=30))
        ]
        
        score -= len(recent_faults) * 5
        
        # 基于维护情况调整
        if equipment.next_maintenance_date:
            days_overdue = (datetime.now() - equipment.next_maintenance_date).days
            if days_overdue > 0:
                score -= days_overdue * 2
        
        # 基于性能指标异常扣分
        recent_metrics = [
            metric for metric in self.performance_metrics
            if (metric.equipment_id == equipment_id and 
                metric.recorded_date >= datetime.now() - timedelta(days=7))
        ]
        
        abnormal_metrics = [m for m in recent_metrics if not m.is_within_normal_range]
        score -= len(abnormal_metrics) * 3
        
        return max(0.0, min(100.0, score))
    
    def get_maintenance_dashboard(self) -> Dict:
        """获取维护仪表板数据"""
        current_date = datetime.now()
        
        # 统计维护任务
        total_tasks = len(self.maintenance_tasks)
        completed_tasks = len([t for t in self.maintenance_tasks.values() 
                             if t.status == MaintenanceStatus.COMPLETED.value])
        in_progress_tasks = len([t for t in self.maintenance_tasks.values() 
                               if t.status == MaintenanceStatus.IN_PROGRESS.value])
        overdue_tasks = len([t for t in self.maintenance_tasks.values() 
                           if (t.scheduled_date < current_date and 
                               t.status == MaintenanceStatus.PLANNED.value)])
        
        # 统计故障
        total_faults = len(self.fault_records)
        open_faults = len([f for f in self.fault_records.values() 
                         if f.status not in [FaultStatus.RESOLVED.value, FaultStatus.CLOSED.value]])
        critical_faults = len([f for f in self.fault_records.values() 
                             if f.severity == FaultSeverity.CRITICAL.value and 
                             f.status not in [FaultStatus.RESOLVED.value, FaultStatus.CLOSED.value]])
        
        # 统计设备状态
        equipment_status_count = defaultdict(int)
        for equipment in self.equipment.values():
            if equipment.is_active:
                equipment_status_count[equipment.status] += 1
        
        # 计算平均维修时间
        completed_faults = [f for f in self.fault_records.values() 
                          if f.status == FaultStatus.RESOLVED.value and f.resolved_date]
        
        avg_repair_time = 0.0
        if completed_faults:
            total_repair_time = sum(f.downtime_hours for f in completed_faults)
            avg_repair_time = round(total_repair_time / len(completed_faults), 2)
        
        # 即将到期的维护
        upcoming_maintenance = []
        for equipment in self.equipment.values():
            if (equipment.next_maintenance_date and 
                equipment.next_maintenance_date <= current_date + timedelta(days=7)):
                upcoming_maintenance.append({
                    'equipment_id': equipment.equipment_id,
                    'equipment_name': equipment.name,
                    'next_maintenance_date': equipment.next_maintenance_date.isoformat(),
                    'days_until_maintenance': (equipment.next_maintenance_date - current_date).days
                })
        
        return {
            'maintenance_summary': {
                'total_tasks': total_tasks,
                'completed_tasks': completed_tasks,
                'in_progress_tasks': in_progress_tasks,
                'overdue_tasks': overdue_tasks,
                'completion_rate': round((completed_tasks / total_tasks * 100), 2) if total_tasks > 0 else 0
            },
            'fault_summary': {
                'total_faults': total_faults,
                'open_faults': open_faults,
                'critical_faults': critical_faults,
                'average_repair_time_hours': avg_repair_time
            },
            'equipment_status': dict(equipment_status_count),
            'upcoming_maintenance': upcoming_maintenance,
            'dashboard_updated': current_date.isoformat()
        }
    
    def export_equipment_data(self, file_path: str, data_type: str = "equipment") -> bool:
        """导出设备数据"""
        try:
            if data_type == "equipment":
                data = []
                for equipment in self.equipment.values():
                    equipment_data = asdict(equipment)
                    # 转换datetime对象为字符串
                    for key, value in equipment_data.items():
                        if isinstance(value, datetime):
                            equipment_data[key] = value.isoformat()
                    data.append(equipment_data)
            
            elif data_type == "maintenance_tasks":
                data = []
                for task in self.maintenance_tasks.values():
                    task_data = asdict(task)
                    for key, value in task_data.items():
                        if isinstance(value, datetime):
                            task_data[key] = value.isoformat()
                    data.append(task_data)
            
            elif data_type == "faults":
                data = []
                for fault in self.fault_records.values():
                    fault_data = asdict(fault)
                    for key, value in fault_data.items():
                        if isinstance(value, datetime):
                            fault_data[key] = value.isoformat()
                    data.append(fault_data)
            
            elif data_type == "performance_metrics":
                data = []
                for metric in self.performance_metrics:
                    metric_data = asdict(metric)
                    for key, value in metric_data.items():
                        if isinstance(value, datetime):
                            metric_data[key] = value.isoformat()
                    data.append(metric_data)
            
            else:
                logger.error(f"不支持的数据类型: {data_type}")
                return False
            
            df = pd.DataFrame(data)
            df.to_csv(file_path, index=False, encoding='utf-8-sig')
            logger.info(f"{data_type} 数据已导出到 {file_path}")
            return True
            
        except Exception as e:
            logger.error(f"导出数据失败: {e}")
            return False

# 示例使用
if __name__ == "__main__":
    # 创建设备管理系统实例
    ems = EquipmentManagementSystem()
    
    # 注册设备
    equipment = Equipment(
        equipment_id="EQ001",
        name="数控机床A",
        model="CNC-2000",
        manufacturer="精密机械公司",
        serial_number="SN123456789",
        category="加工设备",
        location="车间A-01",
        purchase_date=datetime(2020, 1, 15),
        warranty_expiry=datetime(2025, 1, 15),
        specifications={
            "最大加工尺寸": "500x300x200mm",
            "主轴转速": "0-8000rpm",
            "定位精度": "±0.005mm"
        },
        purchase_cost=150000.0,
        current_value=120000.0
    )
    ems.register_equipment(equipment)
    
    # 注册技术员
    technician_data = {
        'technician_id': 'TECH001',
        'name': '张师傅',
        'skills': ['数控维修', '机械维护', '电气检修'],
        'certifications': ['数控维修工证书'],
        'experience_years': 8,
        'hourly_rate': 80.0
    }
    ems.register_technician(technician_data)
    
    # 创建维护计划
    plan_data = {
        'equipment_id': 'EQ001',
        'maintenance_type': MaintenanceType.PREVENTIVE.value,
        'description': '数控机床定期保养',
        'frequency_days': 30,
        'estimated_duration_hours': 4.0,
        'required_parts': [
            {'part_name': '润滑油', 'quantity': 2, 'unit': '升'},
            {'part_name': '过滤器', 'quantity': 1, 'unit': '个'}
        ],
        'required_skills': ['数控维修', '机械维护'],
        'safety_requirements': ['断电操作', '佩戴防护用品'],
        'cost_estimate': 500.0
    }
    
    plan_id = ems.create_maintenance_plan(plan_data)
    if plan_id:
        print(f"维护计划创建成功: {plan_id}")
        
        # 生成维护任务
        tasks = ems.generate_maintenance_tasks(days_ahead=60)
        print(f"生成维护任务: {tasks}")
        
        # 报告故障
        fault_data = {
            'equipment_id': 'EQ001',
            'fault_description': '主轴异响，疑似轴承问题',
            'severity': FaultSeverity.HIGH.value,
            'reported_by': 'OP001',
            'impact_on_production': '影响加工精度，需要立即处理'
        }
        
        fault_id = ems.report_fault(fault_data)
        print(f"故障报告成功: {fault_id}")
        
        # 记录性能指标
        metric_data = {
            'equipment_id': 'EQ001',
            'metric_name': '主轴温度',
            'metric_value': 65.5,
            'unit': '°C',
            'normal_range_min': 40.0,
            'normal_range_max': 70.0,
            'operator_id': 'OP001',
            'notes': '正常运行时测量'
        }
        
        ems.record_performance_metric(metric_data)
        
        # 获取维护仪表板
        dashboard = ems.get_maintenance_dashboard()
        print("维护仪表板:", json.dumps(dashboard, indent=2, default=str, ensure_ascii=False))
        
        # 获取设备性能分析
        performance = ems.get_equipment_performance_analysis('EQ001')
        print("设备性能分析:", json.dumps(performance, indent=2, default=str, ensure_ascii=False))